{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### logistic回归\n",
    "\n",
    "> 理论 《统计学习方法》第六章 逻辑斯谛回归模型\n",
    "> \n",
    "> 代码 numpy version && torch version\n",
    ">\n",
    "> Python3.7"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### sigmod函数\n",
    "\n",
    "$$\n",
    "\\sigma(x) = {1\\over {1+e^{-x}}}\n",
    "$$"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 二项logistic回归模型\n",
    "\n",
    "Y取0|1\n",
    "\n",
    "通过一个线性，然后再logistic函数，转换为条件概率分布P(Y|X)\n",
    "\n",
    "$$\n",
    "P(Y=1|X) = {e^{w\\cdot x + b}\\over {1+e^{w\\cdot x + b}}}\n",
    "$$\n",
    "\n",
    "$$\n",
    "P(Y=1|X) = {1\\over {1+e^{w\\cdot x + b}}}\n",
    "$$"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 几率odds\n",
    "\n",
    "几率是指该事件发生与不发生概论的比值,发生概率为p,则几率是$p\\over{1-p}$。对数几率是$logit(p) = log{p\\over {1-p}}$。对上述的logistic回归，几率是$w\\cdot x + b$,也就是说输出Y=1的对数几率是输入X的线性函数。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 交叉熵损失函数\n",
    "\n",
    "$$\n",
    "L(y,\\hat{y}) = - [y\\log \\hat{y} + (1-y)\\log(1-\\hat{y})]\n",
    "$$\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 参数估计\n",
    "\n",
    "使用极大似然法估计模型参数。\n",
    "\n",
    "假设$P(Y=1|x) = \\pi(x),P(Y=0|x)=1-\\pi(x)$。\n",
    "\n",
    "\n",
    "\n",
    "则有似然函数$\\Pi [\\pi(x_i)]^{y_i}[1-\\pi(x_i)]^{1-y_i}$。\n",
    "\n",
    "（解释：当$y_i=0$时候，需要最大$[1-\\pi(x_i)]^{1-y_i}$。$y_i=1$时同）。\n",
    "\n",
    "\n",
    "\n",
    "对数似然函数(其实就是**负的**交叉熵损失函数)\n",
    "$$\n",
    "L(w,b) = \\Sigma [y_i\\ \\log\\pi(x_i) + (1-y_i)\\ \\log (1-\\pi(x_i)]\\\\ =\\Sigma [y_i\\ \\log{\\pi(x_i)\\over 1-\\pi(x_i)} + \\log(1-\\pi(x_i))]\\\\\n",
    "=\\Sigma [y_i(-(w\\cdot x_i + b)) - log(1+e^{-(w\\cdot x_i + b)})]\n",
    "$$\n",
    "然后$L(w,b)$对$w,b$求导，使用梯度下降法更新$w,b$便可以得到参数估计值\n",
    "$$\n",
    "\\frac{\\partial L(w,b)}{\\partial w} = \\varSigma{(-y_i\\cdot x_i - {e^{-(w\\cdot x_i + b)}\\cdot -x_i\\over{1+ e^{-(w\\cdot x_i + b)}}})} = \\varSigma x_i (\\sigma(x_i) - y_i)\n",
    "\\\\\n",
    "\\frac{\\partial L(w,b)}{\\partial b} = \\varSigma{(-y_i - {e^{-(w\\cdot x_i + b)}\\cdot -x_i\\over{1+ e^{-(w\\cdot x_i + b)}}})} = {\\varSigma (\\sigma(x_i)-y_i)}\n",
    "$$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "from torch import nn\n",
    "import torch.utils.data as Data\n",
    "from sklearn.datasets import make_blobs\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import  accuracy_score\n",
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "def draw_fig(x,y,w,b):\n",
    "    plt.figure(dpi=64,figsize=(4,4))\n",
    "\n",
    "    plt.scatter(x[:,0],x[:,1],c=y)\n",
    "\n",
    "    # 画分离超平面\n",
    "    if w is not None:\n",
    "        x1 = np.arange(-1, 4, 0.1)\n",
    "        x2 = (w[0] * x1 + b) / (-w[1])\n",
    "        plt.plot(x1,x2)\n",
    "\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "outputs": [],
   "source": [
    "x_train,y_train = make_blobs(n_samples=200,\n",
    "                 n_features=2,\n",
    "                 centers=2,\n",
    "                 cluster_std=1,\n",
    "                 random_state=8)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 256x256 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "draw_fig(x_train,y_train,None,None)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "# x_train = np.array([[3.,3.],[4,3],[5,5],[1,1],[0,0],[1,0]])\n",
    "# y_train = np.array([1,1,1,0,0,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 5 % dw is [-0.00080945 -0.00037774],db is -0.00\n",
      "epoch 5 % w is [ 2.88589051 -4.89094582],b is 0.42\n",
      "\n",
      "epoch 10 % dw is [-0.00078391 -0.00036577],db is -0.00\n",
      "epoch 10 % w is [ 2.88986049 -4.88909335],b is 0.42\n",
      "\n",
      "epoch 15 % dw is [-0.00075992 -0.00035451],db is -0.00\n",
      "epoch 15 % w is [ 2.8937075  -4.88729855],b is 0.42\n",
      "\n",
      "epoch 20 % dw is [-0.00073735 -0.00034392],db is -0.00\n",
      "epoch 20 % w is [ 2.89743885 -4.88555801],b is 0.42\n",
      "\n",
      "epoch 25 % dw is [-0.00071606 -0.00033394],db is -0.00\n",
      "epoch 25 % w is [ 2.90106125 -4.88386858],b is 0.42\n",
      "\n",
      "epoch 30 % dw is [-0.00069596 -0.00032451],db is -0.00\n",
      "epoch 30 % w is [ 2.90458082 -4.88222738],b is 0.42\n",
      "\n",
      "epoch 35 % dw is [-0.00067695 -0.00031559],db is -0.00\n",
      "epoch 35 % w is [ 2.90800319 -4.88063179],b is 0.42\n",
      "\n",
      "epoch 40 % dw is [-0.00065894 -0.00030714],db is -0.00\n",
      "epoch 40 % w is [ 2.91133354 -4.87907938],b is 0.42\n",
      "\n",
      "epoch 45 % dw is [-0.00064186 -0.00029912],db is -0.00\n",
      "epoch 45 % w is [ 2.91457664 -4.8775679 ],b is 0.42\n",
      "\n",
      "epoch 50 % dw is [-0.00062563 -0.00029151],db is -0.00\n",
      "epoch 50 % w is [ 2.91773692 -4.8760953 ],b is 0.43\n",
      "\n",
      "epoch 55 % dw is [-0.00061019 -0.00028426],db is -0.00\n",
      "epoch 55 % w is [ 2.92081845 -4.87465965],b is 0.43\n",
      "\n",
      "epoch 60 % dw is [-0.00059549 -0.00027736],db is -0.00\n",
      "epoch 60 % w is [ 2.92382503 -4.87325917],b is 0.43\n",
      "\n",
      "\n",
      "finally get w is [ 2.92382503 -4.87325917], b is 0.43\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 256x256 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "numpy实现\n",
    "\"\"\"\n",
    "def Sigmoid(x):\n",
    "    return 1 / (1+np.exp(-x))\n",
    "\n",
    "def BCELoss(y,yhat):\n",
    "    return -(y*np.log(yhat)+(1-y)*np.log(1-yhat))\n",
    "\n",
    "lr = 1\n",
    "w = np.zeros(x_train.shape[1])\n",
    "b = 0\n",
    "epochs = 60\n",
    "size = len(x_train)\n",
    "\n",
    "yhat_list = np.zeros_like(y_train,dtype=float)\n",
    "\n",
    "for epoch in range(1,epochs+1):\n",
    "    for i,v in enumerate(x_train):\n",
    "        y_hat = float(Sigmoid( (v*w).sum() + b ))\n",
    "        yhat_list[i] = y_hat\n",
    "    db = (yhat_list - y_train).sum() / size\n",
    "    dw = np.zeros_like(w)\n",
    "    for ix in range(len(dw)):\n",
    "        dw[ix] = x_train[:,ix].T.dot((yhat_list-y_train).T)\n",
    "    dw /= size\n",
    "    w -= lr * dw\n",
    "    b -= lr * db\n",
    "    if epoch % 5 == 0:\n",
    "        print(\"epoch {} % dw is {},db is {:.2f}\".format(epoch,dw,db))\n",
    "        print(\"epoch {} % w is {},b is {:.2f}\".format(epoch,w,b))\n",
    "        print()\n",
    " \n",
    "print(\"\\nfinally get w is {}, b is {:.2f}\".format(w,b))\n",
    "\n",
    "draw_fig(x_train,y_train,w,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 20 % loss 0.00\n",
      "epoch 40 % loss 0.00\n",
      "epoch 60 % loss 0.00\n",
      "epoch 80 % loss 0.00\n",
      "epoch 100 % loss 0.00\n",
      "\n",
      "finally get w is [ 1.6854587 -2.5433536], b is 0.36\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 256x256 with 1 Axes>",
      "image/png": "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yy+/zNSpU3n88cervG7QPV02bNjAunXryMzMZMCAAWzcuLFKbYiLi6N58+a0bt0ah8PBzJkzq7T+whR+L+Pj4zl58mSp7z0nWsyEhAQyMzPzf+fm5ua3XlWJz+djyJAh/POf/+T888+v0rrnzZtHp06dSEpKqtJ6C5OYmEhycjIxMTE0btwYu91OdnZ2ldqwYMECjhw5wo4dO9iyZQujR4/G54sQAb4KKPxeZmVllSqgwCnOCWF26dKFpUuX4vP52L17N0lJSWha1T6alJIRI0bQv39/Bg0aVKV1A6xfv54lS5bQv39/FixYwKOPPsrhw4er1IYuXbqQlpaW343MysoiNja2Sm2QUpKYmIimacTExOByuapNmD169MiPTpCSkkLPnj1Lf3PFD4Orhw8//FBefvnlMjk5Wa5fv77K6587d6602WyyZ8+esmfPnvKRRx6pchtOcccdd1TL5I+UUn766acyOTlZdu7cWX7//fdVXr/f75d33HGH7Natm+zUqZMcP358ldU9cOBA2axZM9muXTs5cuRImZeXJ2+55RbZrVs3OXToUOl2u0tdlvL8UShqIOdEV1ahONdQwlQoaiBKmApFDUQJU6GogShhKhQ1ECVMhaIGooSpUNRA/h9Md5L6kCedyQAAAABJRU5ErkJggg==\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "pytorch实现\n",
    "\"\"\"\n",
    "class LogisticReg(nn.Module):\n",
    "    def __init__(self,n):\n",
    "        super(LogisticReg,self).__init__()\n",
    "        self.linear = nn.Linear(n,1)\n",
    "        self.sigmoid = nn.Sigmoid()\n",
    "\n",
    "    def forward(self,x):\n",
    "        x = self.linear(x)\n",
    "        x = self.sigmoid(x)\n",
    "        return x\n",
    "\n",
    "lr = 0.1\n",
    "epochs = 100\n",
    "batch_size = 4\n",
    "\n",
    "x_t = torch.from_numpy(x_train).float()\n",
    "y_t = torch.from_numpy(y_train).float()\n",
    "dataset = Data.TensorDataset(x_t,y_t)\n",
    "data_iter = Data.DataLoader(\n",
    "    dataset=dataset,\n",
    "    batch_size=batch_size,\n",
    "    shuffle=True,\n",
    "    num_workers=0 # 多线程，windows需要设置为0\n",
    ")\n",
    "\n",
    "net = LogisticReg(x_train.shape[1])\n",
    "# 模型参数初始化\n",
    "nn.init.normal_(net.linear.weight,mean=0,std=1)\n",
    "nn.init.constant_(net.linear.bias,val=0)\n",
    "loss = nn.BCELoss()\n",
    "optimizer = torch.optim.SGD(net.parameters(),lr=lr)\n",
    "\n",
    "for epoch in range(1,epochs+1):\n",
    "    for x,y in data_iter:\n",
    "        y_hat = net(x)\n",
    "        y_hat = y_hat.squeeze()     # 拉伸为一维向量\n",
    "        l = loss(y_hat,y)\n",
    "\n",
    "        optimizer.zero_grad()\n",
    "        l.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "    if epoch%20==0:\n",
    "        print('epoch {} % loss {:.2f}'.format(epoch,l.item()))\n",
    "\n",
    "w = net.linear.weight[0].detach().numpy()\n",
    "b = net.linear.bias.data[0].numpy()\n",
    "print(\"\\nfinally get w is {}, b is {:.2f}\".format(w,b))\n",
    "\n",
    "draw_fig(x_train,y_train,w,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4 (default, Aug  9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)]"
  },
  "vscode": {
   "interpreter": {
    "hash": "3c874ee3d65450ef899cacaa06bdca40f9e4450c5e631a94911db3215dbda5b8"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
